// Service Worker for PWA functionality
const CACHE_NAME = 'xiaozhi-medical-v1.0.0'
const STATIC_CACHE = 'xiaozhi-static-v1.0.0'
const DYNAMIC_CACHE = 'xiaozhi-dynamic-v1.0.0'

// 需要缓存的静态资源
const STATIC_ASSETS = [
  '/',
  '/index.html',
  '/manifest.json',
  '/favicon.ico',
  '/OIP.webp',
  // 添加其他静态资源
]

// 需要缓存的API路径
const API_CACHE_PATTERNS = [
  /\/api\/user\/profile/,
  /\/api\/health\/records/,
  /\/api\/appointments/
]

// 安装事件 - 缓存静态资源
self.addEventListener('install', event => {
  console.log('Service Worker installing...')
  event.waitUntil(
    caches.open(STATIC_CACHE)
      .then(cache => {
        console.log('Caching static assets')
        return cache.addAll(STATIC_ASSETS)
      })
      .then(() => {
        console.log('Static assets cached successfully')
        return self.skipWaiting()
      })
      .catch(error => {
        console.error('Failed to cache static assets:', error)
      })
  )
})

// 激活事件 - 清理旧缓存
self.addEventListener('activate', event => {
  console.log('Service Worker activating...')
  event.waitUntil(
    caches.keys()
      .then(cacheNames => {
        return Promise.all(
          cacheNames.map(cacheName => {
            if (cacheName !== STATIC_CACHE && cacheName !== DYNAMIC_CACHE) {
              console.log('Deleting old cache:', cacheName)
              return caches.delete(cacheName)
            }
          })
        )
      })
      .then(() => {
        console.log('Service Worker activated')
        return self.clients.claim()
      })
  )
})

// 拦截网络请求
self.addEventListener('fetch', event => {
  const { request } = event
  const url = new URL(request.url)

  // 跳过非GET请求
  if (request.method !== 'GET') {
    return
  }

  // 跳过chrome-extension和其他协议
  if (!url.protocol.startsWith('http')) {
    return
  }

  event.respondWith(
    handleRequest(request)
  )
})

// 处理请求的策略
async function handleRequest(request) {
  const url = new URL(request.url)
  
  try {
    // 静态资源 - Cache First策略
    if (isStaticAsset(request)) {
      return await cacheFirst(request, STATIC_CACHE)
    }
    
    // API请求 - Network First策略
    if (isApiRequest(request)) {
      return await networkFirst(request, DYNAMIC_CACHE)
    }
    
    // 页面请求 - Stale While Revalidate策略
    if (isPageRequest(request)) {
      return await staleWhileRevalidate(request, DYNAMIC_CACHE)
    }
    
    // 其他请求 - Network Only
    return await fetch(request)
  } catch (error) {
    console.error('Request failed:', error)
    return await getOfflineFallback(request)
  }
}

// Cache First策略 - 优先从缓存获取
async function cacheFirst(request, cacheName) {
  const cache = await caches.open(cacheName)
  const cachedResponse = await cache.match(request)
  
  if (cachedResponse) {
    return cachedResponse
  }
  
  const networkResponse = await fetch(request)
  if (networkResponse.ok) {
    cache.put(request, networkResponse.clone())
  }
  
  return networkResponse
}

// Network First策略 - 优先从网络获取
async function networkFirst(request, cacheName) {
  const cache = await caches.open(cacheName)
  
  try {
    const networkResponse = await fetch(request)
    if (networkResponse.ok) {
      cache.put(request, networkResponse.clone())
    }
    return networkResponse
  } catch (error) {
    const cachedResponse = await cache.match(request)
    if (cachedResponse) {
      return cachedResponse
    }
    throw error
  }
}

// Stale While Revalidate策略 - 返回缓存同时更新
async function staleWhileRevalidate(request, cacheName) {
  const cache = await caches.open(cacheName)
  const cachedResponse = await cache.match(request)
  
  // 后台更新缓存
  const fetchPromise = fetch(request).then(networkResponse => {
    if (networkResponse.ok) {
      cache.put(request, networkResponse.clone())
    }
    return networkResponse
  })
  
  // 如果有缓存，立即返回缓存
  if (cachedResponse) {
    return cachedResponse
  }
  
  // 否则等待网络响应
  return await fetchPromise
}

// 判断是否为静态资源
function isStaticAsset(request) {
  const url = new URL(request.url)
  return url.pathname.match(/\.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf)$/)
}

// 判断是否为API请求
function isApiRequest(request) {
  const url = new URL(request.url)
  return API_CACHE_PATTERNS.some(pattern => pattern.test(url.pathname))
}

// 判断是否为页面请求
function isPageRequest(request) {
  const url = new URL(request.url)
  return request.destination === 'document' || 
         url.pathname === '/' || 
         url.pathname.startsWith('/login') ||
         url.pathname.startsWith('/dashboard')
}

// 离线回退页面
async function getOfflineFallback(request) {
  if (request.destination === 'document') {
    const cache = await caches.open(STATIC_CACHE)
    return await cache.match('/') || new Response('离线模式下无法访问此页面', {
      status: 503,
      statusText: 'Service Unavailable',
      headers: { 'Content-Type': 'text/plain; charset=utf-8' }
    })
  }
  
  return new Response('网络连接失败', {
    status: 503,
    statusText: 'Service Unavailable',
    headers: { 'Content-Type': 'text/plain; charset=utf-8' }
  })
}

// 监听消息事件
self.addEventListener('message', event => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting()
  }
  
  if (event.data && event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage({ version: CACHE_NAME })
  }
})

// 后台同步事件
self.addEventListener('sync', event => {
  if (event.tag === 'background-sync') {
    event.waitUntil(doBackgroundSync())
  }
})

// 执行后台同步
async function doBackgroundSync() {
  console.log('Performing background sync...')
  // 这里可以添加离线时需要同步的数据
  // 例如：同步离线时的用户操作、上传待发送的消息等
}

// 推送通知事件
self.addEventListener('push', event => {
  if (event.data) {
    const data = event.data.json()
    const options = {
      body: data.body,
      icon: '/favicon.ico',
      badge: '/favicon.ico',
      vibrate: [100, 50, 100],
      data: {
        dateOfArrival: Date.now(),
        primaryKey: data.primaryKey
      },
      actions: [
        {
          action: 'explore',
          title: '查看详情',
          icon: '/favicon.ico'
        },
        {
          action: 'close',
          title: '关闭',
          icon: '/favicon.ico'
        }
      ]
    }
    
    event.waitUntil(
      self.registration.showNotification(data.title, options)
    )
  }
})

// 通知点击事件
self.addEventListener('notificationclick', event => {
  event.notification.close()
  
  if (event.action === 'explore') {
    event.waitUntil(
      clients.openWindow('/')
    )
  }
})